import React, { useState } from 'react';
import { ThemeProvider } from './components/theme-provider';
import { Button } from './components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from './components/ui/card';
import { Tabs, TabsContent, TabsList, TabsTrigger } from './components/ui/tabs';
import { Toaster } from './components/ui/toaster';
import MediaUpload from './components/media-upload';
import TargetInput from './components/target-input';
import ResultDisplay from './components/result-display';
import VoiceFeedback from './components/voice-feedback';
import { useToast } from './components/ui/use-toast';

// 定义API基础URL
const API_BASE_URL = 'http://localhost:8000';

// 定义应用程序的主题颜色
const themeColors = {
  primary: '#1a237e', // 深蓝色
  secondary: '#f5f5f5', // 浅灰色
  accent: '#ff8f00', // 橙色
};

// 定义检测结果类型
interface DetectionResult {
  detected: boolean;
  confidence?: number;
  direction?: string;
  distance?: string;
  boundingBox?: {
    x: number;
    y: number;
    width: number;
    height: number;
  };
  message?: string;
  processTime?: number;
  angle?: number;
  depth_estimate?: number;
}

function App() {
  const { toast } = useToast();
  const [activeTab, setActiveTab] = useState<string>('upload');
  const [mediaFile, setMediaFile] = useState<File | null>(null);
  const [mediaType, setMediaType] = useState<'image' | 'video' | null>(null);
  const [targetObject, setTargetObject] = useState<string>('');
  const [isProcessing, setIsProcessing] = useState<boolean>(false);
  const [detectionResult, setDetectionResult] = useState<DetectionResult | null>(null);
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
  const [apiError, setApiError] = useState<string | null>(null);

  // 处理媒体文件上传
  const handleMediaUpload = (file: File) => {
    const fileType = file.type.startsWith('image/') ? 'image' : 'video';
    setMediaFile(file);
    setMediaType(fileType);
    
    // 创建预览URL
    const url = URL.createObjectURL(file);
    setPreviewUrl(url);
    
    toast({
      title: '文件已上传',
      description: `已成功上传${fileType === 'image' ? '图片' : '视频'}文件`,
    });
    
    // 自动切换到目标输入标签页
    setActiveTab('target');
  };

  // 处理目标物体输入
  const handleTargetInput = (target: string) => {
    setTargetObject(target);
    toast({
      title: '目标已设置',
      description: `将寻找目标物体: ${target}`,
    });
    
    // 自动切换到结果标签页
    setActiveTab('result');
  };

  // 处理开始识别
  const handleStartDetection = async () => {
    if (!mediaFile || !targetObject) {
      toast({
        title: '无法开始识别',
        description: '请先上传媒体文件并输入目标物体',
        variant: 'destructive',
      });
      return;
    }
    
    setIsProcessing(true);
    setApiError(null);
    
    try {
      // 创建FormData对象
      const formData = new FormData();
      formData.append('file', mediaFile);
      formData.append('target', targetObject);
      
      // 根据媒体类型选择API端点
      const endpoint = mediaType === 'image' ? '/detect/image' : '/detect/video';
      
      // 发送请求到后端API
      const response = await fetch(`${API_BASE_URL}${endpoint}`, {
        method: 'POST',
        body: formData,
      });
      
      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.detail || '服务器错误');
      }
      
      // 解析响应数据
      const result = await response.json();
      setDetectionResult(result);
      
      // 生成语音反馈
      if (result.message) {
        const speech = new SpeechSynthesisUtterance(result.message);
        speech.lang = 'zh-CN';
        window.speechSynthesis.speak(speech);
      }
    } catch (error) {
      console.error('API请求失败:', error);
      setApiError(error instanceof Error ? error.message : '未知错误');
      
      toast({
        title: '识别失败',
        description: `无法完成识别: ${error instanceof Error ? error.message : '未知错误'}`,
        variant: 'destructive',
      });
    } finally {
      setIsProcessing(false);
    }
  };

  // 处理重置
  const handleReset = () => {
    setMediaFile(null);
    setMediaType(null);
    setTargetObject('');
    setDetectionResult(null);
    setPreviewUrl(null);
    setApiError(null);
    setActiveTab('upload');
    
    // 如果有预览URL，释放它
    if (previewUrl) {
      URL.revokeObjectURL(previewUrl);
    }
    
    toast({
      title: '已重置',
      description: '所有数据已清除，可以开始新的检测',
    });
  };

  // 当组件卸载时清理预览URL
  React.useEffect(() => {
    return () => {
      if (previewUrl) {
        URL.revokeObjectURL(previewUrl);
      }
    };
  }, [previewUrl]);

  return (
    <ThemeProvider defaultTheme="light" storageKey="ui-theme">
      <div className="min-h-screen bg-secondary p-4 md:p-8">
        <header className="bg-primary text-white p-4 rounded-lg mb-6 shadow-md">
          <div className="container mx-auto flex justify-between items-center">
            <h1 className="text-2xl font-bold">目标物体识别与定位系统</h1>
            <div className="flex gap-2">
              <Button variant="outline" className="text-white border-white hover:bg-primary/80">
                帮助
              </Button>
              <Button variant="outline" className="text-white border-white hover:bg-primary/80">
                设置
              </Button>
            </div>
          </div>
        </header>

        <main className="container mx-auto">
          <Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
            <TabsList className="grid w-full grid-cols-3">
              <TabsTrigger value="upload">媒体上传</TabsTrigger>
              <TabsTrigger value="target">目标输入</TabsTrigger>
              <TabsTrigger value="result">识别结果</TabsTrigger>
            </TabsList>
            
            <TabsContent value="upload">
              <Card>
                <CardHeader>
                  <CardTitle>上传图片或视频</CardTitle>
                </CardHeader>
                <CardContent>
                  <MediaUpload onUpload={handleMediaUpload} />
                </CardContent>
              </Card>
            </TabsContent>
            
            <TabsContent value="target">
              <Card>
                <CardHeader>
                  <CardTitle>输入目标物体</CardTitle>
                </CardHeader>
                <CardContent>
                  <TargetInput 
                    onSubmit={handleTargetInput} 
                    disabled={!mediaFile}
                    previewUrl={previewUrl}
                    mediaType={mediaType}
                  />
                </CardContent>
              </Card>
            </TabsContent>
            
            <TabsContent value="result">
              <Card>
                <CardHeader>
                  <CardTitle>识别结果</CardTitle>
                </CardHeader>
                <CardContent>
                  <ResultDisplay 
                    result={detectionResult}
                    isProcessing={isProcessing}
                    targetObject={targetObject}
                    previewUrl={previewUrl}
                    mediaType={mediaType}
                    error={apiError}
                  />
                  
                  <div className="mt-6 flex flex-col md:flex-row gap-4">
                    <Button 
                      onClick={handleStartDetection} 
                      disabled={!mediaFile || !targetObject || isProcessing}
                      className="bg-accent hover:bg-accent/90 text-white"
                    >
                      {isProcessing ? '识别中...' : '开始识别'}
                    </Button>
                    <Button 
                      onClick={handleReset} 
                      variant="outline"
                    >
                      重置
                    </Button>
                  </div>
                  
                  {detectionResult && detectionResult.detected && (
                    <div className="mt-6">
                      <VoiceFeedback 
                        result={detectionResult}
                        targetObject={targetObject}
                      />
                    </div>
                  )}
                </CardContent>
              </Card>
            </TabsContent>
          </Tabs>
        </main>
        
        <footer className="mt-8 text-center text-sm text-gray-500">
          <p>目标物体识别与定位系统 &copy; {new Date().getFullYear()}</p>
        </footer>
      </div>
      <Toaster />
    </ThemeProvider>
  );
}

export default App;